#Copyright 2012 Elias Farhan
#
#This file is part of Squirrel.
#
#Squirrel is free software: you can redistribute it and/or modify it under the terms of the GNU General 
#Public License as published by the Free Software Foundation, either version 3 of the License, or (at your 
#option) any later version.
#
#Squirrel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
#See the GNU General Public License for more details.

#Character editor
import pygame
import Tkinter
from Tkinter import *

from threading import Thread, Lock
import os
import sys
import re
sys.path.insert(0, '..')
from client.game.gameobject import Character
from client.game.box import Box
from client.game.xmlreader import XML2char
from client.game.animation import State
from toXML import char2XML

load = False
character = None
available = Lock()
currentState = 0
class TkinterWindows(Thread):

	def __init__(self):
		Thread.__init__(self)
	def setCurrentState(self):
		global currentState
		self.stentry.set(str(currentState))
	def save(self):
		global character, available
		filename = "../data/xml/character/"+self.label.get()+".xml"
		available.acquire()
		#save character
		(char2XML(character)).write(filename)
		available.release()
	def loadstate(self, dirname):
		flist = []
		for fname in os.listdir("../data/sprites/"+dirname+"/"):
			flist.append(fname)
		flist = sorted(flist)
		state = []
		frames = []
		
		origin_count = 0
		count = 0
		i = 1
		#iiiiiiiiiiiiiiii
		while ((i != 0) and(count<len(flist))):
			m = re.match('\w+'+str(i)+'\d\d\.png', flist[count])
			if(m):
				#jjjjjjjjjjjjjjjjjjj
				j = 1
				while((j != 0) and(count<len(flist))):
					m = re.match('\w+'+str(i)+str(j)+'\d\.png', flist[count])
					if(m):
						#kkkkkkkkkkkkkkkk
						k = 1
						while((k!=0)and(count<len(flist))):

							m = re.match('\w+'+str(i)+str(j)+str(k)+'\.png', flist[count])
							if(not m):
								count-=1
								break
							count+=1
							k=(k+1)%10
						frames.append(k-1)
						#kkkkkkkkkkkkkkkkkk
					else:
						count-=1
						break
					count+=1
					j=(j+1)%10
				#jjjjjjjjjjjjjjjjj
				state.append(State("State"+str(i), 0, tuple(frames), origin_count))
				frames = []
				origin_count = count+1
			else:
				break
			count+=1
			i=(i+1)%10
			#iiiiiiiiiiiiiiiiiii
		return state
		
	def loadprocess(self):
		global character, available, load
		self.boxeslistbox.delete(0, self.boxeslistbox.size())
		self.currentstatelistbox.delete(0, self.currentstatelistbox.size())
		filename = self.label.get()
		try:
			c = XML2char("../data/xml/character/"+filename+".xml")
			
		except IOError:
			c = Character(tuple(int(v) for v in re.findall("\d+", self.posentry.get())), tuple(int(v) for v in re.findall("\d+", self.sizeentry.get())), filename)
			c.movement.state = self.loadstate(filename)
		available.acquire()
		load = True
		character = c
		for state in character.movement.state:
			self.currentstatelistbox.insert(END, state.name)
			for box in state.boxes:
				self.boxeslistbox.insert(END, box)
		available.release()

	def run(self):
		global currentState
		self.tk = Tk()
		self.load = Tkinter.Frame(self.tk,)
		self.load.pack()
		
		self.sizeframe = Tkinter.Frame(self.load)
		self.size = Tkinter.Label(self.sizeframe, text="Size")
		self.size.pack(side="left")
		self.sizeentry = Tkinter.Entry(self.sizeframe)
		self.sizeentry.pack()
		self.sizeframe.pack()
		
		self.label = Tkinter.Entry(self.load)
		self.label.pack()
		self.button = Tkinter.Button(self.load, text="Load", command=self.loadprocess)

		self.button.pack()
		
		self.stat = Tkinter.Frame(self.tk)
		self.stat.pack()
		
		self.state = Tkinter.Frame(self.stat)
		self.statelabel = Tkinter.Label(self.state, text="State")
		self.stentry = Tkinter.StringVar()
		self.stateentry = Tkinter.Label(self.state, textvariable =self.stentry)
		self.statelabel.pack(side="left")
		self.stateentry.pack(side="right")
		self.state.pack()
		
		self.speed = Tkinter.Frame(self.stat)
		self.speedlabel = Tkinter.Label(self.speed, text="Speed")
		self.speedentry = Tkinter.Entry(self.speed)
		self.speedlabel.pack(side="left")
		self.speedentry.pack(side="right")
		self.speed.pack()
		
		self.frames = Tkinter.Frame(self.stat)
		self.frameslabel = Tkinter.Label(self.frames, text="Frames")
		self.framesentry = Tkinter.Entry(self.frames)
		self.frameslabel.pack(side="left")
		self.framesentry.pack(side="right")
		self.frames.pack()
		
		self.pos = Tkinter.Frame(self.stat)
		self.poslabel = Tkinter.Label(self.pos, text="pos")
		self.posentry = Tkinter.Entry(self.pos)
		self.poslabel.pack(side="left")
		self.posentry.pack(side="right")
		self.pos.pack()
		
		self.boxes = Tkinter.Frame(self.stat)
		self.boxeslistbox = Tkinter.Listbox(self.boxes)
		self.boxeslistbox.pack()
		self.boxes.pack()
		
		self.mousepos = Tkinter.Frame(self.stat)
		self.mptext = Tkinter.StringVar()
		self.mousepostext = Tkinter.Label(self.mousepos, textvariable=self.mptext)
		self.mousepostext.pack()
		self.mousepos.pack()
		
		self.savebutton = Tkinter.Button(self.stat, text="Save", command=self.save)
		self.savebutton.pack()
		
		self.statewindow = Tkinter.Toplevel()
		self.currentstatelabel = Tkinter.Label(self.statewindow, text="currentState")
		self.currentstateentry = Tkinter.Entry(self.statewindow)
		self.currentstatelistbox = Tkinter.Listbox(self.statewindow, selectmode=SINGLE)
		self.currentstatelabel.pack()
		self.currentstateentry.pack()
		self.currentstatelistbox.pack()

		
		self.tk.mainloop()
	def addBox(self, box):
		global character
		self.boxeslistbox.insert(END, box[0])
		character.addBox(box[0], box[1])
	def getBoxes(self, state):
		return character.movement.state[state].box
	def setmousepos(self, n):
		self.mptext.set(str(n))
	def nullboxlist(self):
		self.boxeslistbox.delete(0, self.boxeslistbox.size())
		
	
	
class SpriteBox(pygame.sprite.Sprite):
	#blue box for hitbox
	#red box for damagebox
	#grey box for collisionbox
	def __init__(self, initial_pos):
		self.pos = initial_pos
		self.origin = self.pos
		self.end = (self.pos[0]+2, self.pos[1]+2)
		self.image = pygame.Surface((2, 2))
	def setpos(self, pos):
		if((pos[0]<self.pos[0]) and (pos[1]<self.pos[1])):
			self.origin = pos
			self.end = self.pos
		elif((pos[0]>self.pos[0]) and (pos[1]>self.pos[1])):
			self.origin = self.pos
			self.end = pos
		elif((pos[0]>self.pos[0]) and (pos[1]<self.pos[1])):
			self.origin = (self.pos[0], pos[1])
			self.end = (pos[0], self.pos[1])
		else:
			self.end = (self.pos[0], pos[1])
			self.origin = (pos[0], self.pos[1])
		if(self.end[0] == self.origin[0]):
			self.end= (self.end[0]+2, self.end[1])
		if(self.end[1] == self.origin[1]):
			self.end= (self.end[0], self.end[1]+2)
		self.image = pygame.Surface((self.end[0]-self.origin[0], self.end[1]-self.origin[1]))
		self.image.fill((0, 0, 255))
		self.image.set_alpha(100)
		self.rect = self.image.get_rect()
def load_image():
	global available, character
	img = []
	for i in xrange(1, len(character.movement.state)):
		for j in xrange(1, len(character.movement.state[i].frames)):
			for k in xrange(1, character.movement.state[i].frames[j]):
				m = re.match("(\w+)\/(\w+)", character.filename)
				filename = character.filename+'/'+m.group(2)
				image = pygame.image.load("../data/sprites/"+filename+str(i)+str(j)+str(k)+".png")
				image = pygame.transform.scale(image, character.size)
				image = image.convert_alpha()
				img.append(image)
	character.setImage(img)
	
def newboxlist():
	global character
	boxlist = []
	for box in character.movement.state[currentState].boxes:
		boxlist.append(SpriteBox(box.origin))
		boxlist[len(boxlist)-1].setpos(box.end)
	return boxlist
def main():
	global character, load, currentState, available
	fen1 = TkinterWindows()
	fen1.start()

	pygame.init()
	fpsClock = pygame.time.Clock()
	screen = pygame.display.set_mode((600, 400))
	background = pygame.Surface(screen.get_size())
	background = background.convert()
	background.fill((250, 250, 250))
	pygame.display.set_caption('Character Editor v0.5')
	screen.blit(background, (0, 0))
	pygame.display.flip()
	over = False
	boxstate = 0 #0: grey, 1: red, 2: blue
	boxtmp = None
	boxsprite = None
	boxlist = []
	count = 0
	while not over :
		#print fpsClock.get_fps()
		fpsClock.tick(30)
		available.acquire()
		if(load):
			boxlist = newboxlist()
			load = False
		available.release()
		if (boxsprite != None):
			boxsprite.setpos(pygame.mouse.get_pos())
		try:
			fen1.setmousepos(pygame.mouse.get_pos())
		except Exception:
			pass

		for event in pygame.event.get():
			if event.type == pygame.MOUSEBUTTONDOWN:
				if(pygame.mouse.get_pressed()[0]):
					boxtmp = pygame.mouse.get_pos()
					boxsprite = SpriteBox(boxtmp)
			elif event.type == pygame.MOUSEBUTTONUP:
				if(boxtmp != None):
					available.acquire()
					fen1.addBox((Box(boxtmp, pygame.mouse.get_pos()), currentState))
					available.release()
					boxlist.append(boxsprite)
					boxsprite = None
					boxtmp = None
			elif event.type == pygame.KEYDOWN:
				if (event.key == pygame.K_DELETE):
					available.acquire()
					character.movement.state[currentState].boxes = []
					boxlist = newboxlist()
					fen1.nullboxlist()
					available.release()
				#state change
				else:
					try:
						n = int(event.key)-pygame.K_1
						currentState = n
						fen1.setCurrentState()
						boxlist = []
						available.acquire()
						boxlist = newboxlist()
						available.release()
					except IOError:
						pass
		#draw the rest
		screen.blit(background, (0, 0))
		
		available.acquire()
		if((character!= None) and (character.image!=None)):
			screen.blit(character.image, (0, 0))
		elif(character != None):
			load_image()
		available.release()
		for box in boxlist:
			screen.blit(box.image, box.origin)
		if (boxsprite != None):
			screen.blit(boxsprite.image, boxsprite.origin)
		pygame.display.flip()
	
if __name__ == "__main__":
	main()

